package com.orange.common.base

import android.app.Activity
import android.content.Intent
import android.content.res.Resources
import android.os.Bundle
import android.util.SparseArray
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.AdaptScreenUtils
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.KeyboardUtils
import com.blankj.utilcode.util.ScreenUtils
import com.lxj.xpopup.core.BasePopupView
import com.orange.common.BR
import com.orange.common.ktx.intentOf
import com.orange.common.popup.LoadingPopup
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.Random
import kotlin.math.pow

abstract class BaseActivity<DB : ViewDataBinding> : AppCompatActivity() {

    protected lateinit var binding: DB

    protected abstract val viewModel: BaseViewModel?

    /**
     * 根据设计图设置宽度dp
     */
    protected var designWidth = 360

    protected var designHeight = 360

    /**
     * Activity 回调集合
     */
    private val activityCallbacks: SparseArray<OnActivityCallback?> by lazy { SparseArray(1) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initLayout()
        initView()
        initData()
    }

    /**
     * 初始化布局
     */
    open fun initLayout() {
        binding = DataBindingUtil.setContentView(this, getLayoutId())
        binding.run {
            //默认绑定 lifecycleOwner 和 viewModel
            lifecycleOwner = this@BaseActivity
            setVariable(BR.vm, viewModel)
            executePendingBindings()

            //点击外部隐藏软键盘
            root.setOnClickListener {
                KeyboardUtils.hideSoftInput(it)
            }
        }
    }

    /**
     * 获取布局 ID
     */
    protected abstract fun getLayoutId(): Int

    /**
     * 初始化控件
     */
    protected abstract fun initView()


    /**
     * 初始化数据
     */
    protected abstract fun initData()

    override fun getResources(): Resources {
        /**
         * 屏幕适配 https://juejin.cn/post/6844903742135861261
         */
        if (ScreenUtils.isPortrait()) {
            return AdaptScreenUtils.adaptWidth(super.getResources(), designWidth)
        }
        return AdaptScreenUtils.adaptWidth(super.getResources(), designHeight)
    }

    /**
     * 自动显示加载框
     */
    fun loadingLaunch(
        popup: BasePopupView = LoadingPopup(this),
        dispatcher: CoroutineDispatcher = Dispatchers.Main,
        block: suspend CoroutineScope.() -> Unit
    ) {
        lifecycleScope.launch(dispatcher) {
            popup.show()
            block()
        }.invokeOnCompletion {
            popup.dismiss()
        }
    }

    /**
     * 双击返回键退出 App
     */
    fun pressBackTwiceToExitApp(
        delayMillis: Long = 2000,
        owner: LifecycleOwner = this,
        onFirstBackPressed: () -> Unit
    ) =
        onBackPressedDispatcher.addCallback(owner, object : OnBackPressedCallback(true) {
            private var lastBackTime: Long = 0

            override fun handleOnBackPressed() {
                val currentTime = System.currentTimeMillis()
                if (currentTime - lastBackTime > delayMillis) {
                    onFirstBackPressed()
                    lastBackTime = currentTime
                } else {
                    lifecycleScope.launch {
                        ActivityUtils.finishAllActivities(true)
                        delay(200)
                        AppUtils.exitApp()
                    }
                }
            }
        })

    override fun onDestroy() {
        super.onDestroy()
        binding.unbind()
    }

    /**
     * 简化startActivityForResult
     */
    inline fun <reified T : Activity> startActivityForResult(
        vararg params: Pair<String, Any?>,
        noinline block: ((resultCode: Int, data: Intent?) -> Unit)? = null,
    ) {

        val callback = block?.let {
            object : OnActivityCallback {
                override fun onActivityResult(resultCode: Int, data: Intent?) {
                    block(resultCode, data)
                }
            }
        }
        startActivityForResult(intentOf<T>(*params), null, callback)
    }

    /**
     * startActivityForResult 方法优化
     * https://github.com/getActivity/AndroidProject-Kotlin/blob/master/library/base/src/main/java/com/hjq/base/BaseActivity.kt
     */
    @Suppress("deprecation")
    override fun startActivityForResult(intent: Intent, requestCode: Int, options: Bundle?) {
        // 隐藏软键，避免内存泄漏
        KeyboardUtils.hideSoftInput(this)
        // 查看源码得知 startActivity 最终也会调用 startActivityForResult
        super.startActivityForResult(intent, requestCode, options)
    }

    @Suppress("deprecation")
    open fun startActivityForResult(
        intent: Intent,
        options: Bundle? = null,
        callback: OnActivityCallback?,
    ) {
        // 请求码必须在 2 的 16 次方以内
        val requestCode: Int = Random().nextInt(2.0.pow(16.0).toInt())
        activityCallbacks.put(requestCode, callback)
        startActivityForResult(intent, requestCode, options)
    }

    @Suppress("deprecation")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        var callback: OnActivityCallback?
        if ((activityCallbacks.get(requestCode).also { callback = it }) != null) {
            callback?.onActivityResult(resultCode, data)
            activityCallbacks.remove(requestCode)
            return
        }
        super.onActivityResult(requestCode, resultCode, data)
    }

    interface OnActivityCallback {

        /**
         * 结果回调
         *
         * @param resultCode        结果码
         * @param data              数据
         */
        fun onActivityResult(resultCode: Int, data: Intent?)
    }
}